/**
 * Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
 *
 *         Project home : http://code.daikit.com/daikit4gxt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daikit.daikit4gxt.client.ui.forms;

import java.util.List;
import java.util.Set;

import com.daikit.commons.shared.bean.AbstractDkBeanWithId;
import com.daikit.daikit4gxt.client.model.propertyaccess.EditDeletePropertyAccess;
import com.daikit.daikit4gxt.client.ui.edit.AddButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.AddButtonSelectEvent.AddButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.CreateButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.CreateButtonSelectEvent.CreateButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.DeleteButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.DeleteButtonSelectEvent.DeleteButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.EditButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.EditButtonSelectEvent.EditButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.forms.MyEditorGrid.Functionality;
import com.google.gwt.event.shared.HandlerRegistration;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.PropertyAccess;
import com.sencha.gxt.widget.core.client.Component;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.Grid;


/**
 * A Dual Grid made of 2 {@link MyEditorGrid}s
 * 
 * @author tcaselli
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 * @param <M1>
 *           type of the left grid (source)
 * @param <M2>
 *           type of the right grid (target)
 */
public abstract class MyDualEditorGrid<M1 extends AbstractDkBeanWithId, M2 extends AbstractDkBeanWithId> extends MyDualGrid<M1, M2>
{

	private final MyEditorGrid<M1> leftEditorGrid;
	private final MyEditorGrid<M2> rightEditorGrid;


	/**
	 * Constructor creating the left list store
	 * 
	 * @param editorRightStore
	 *           the {@link ListStore} that will be edited
	 * @param leftProperties
	 *           {@link PropertyAccess} for left grid
	 * @param rightProperties
	 *           {@link PropertyAccess} for right grid
	 * @param leftColumnConfigs
	 *           {@link ColumnConfig} list for left grid
	 * @param rightColumnConfigs
	 *           {@link ColumnConfig} list for right grid
	 * @param leftFunctionalities
	 *           a {@link Set} of {@link Functionality} for left {@link MyEditorGrid}
	 * @param rightFunctionalities
	 *           a {@link Set} of {@link Functionality} for right {@link MyEditorGrid}
	 * @param bottomToolbarVisible
	 *           a boolean indicating whether to show bottom toobar or not
	 * @param dualFunctionalities
	 *           a succession of {@link DualFunctionality} (don't fill this argument or give
	 *           {@link DualFunctionality#ALL} to have all functionalities)
	 */
	@SuppressWarnings(
	{ "javadoc" })
	public MyDualEditorGrid(final ListStore<M2> editorRightStore, final EditDeletePropertyAccess<M1> leftProperties,
			final EditDeletePropertyAccess<M2> rightProperties, final List<ColumnConfig<M1, ?>> leftColumnConfigs,
			final List<ColumnConfig<M2, ?>> rightColumnConfigs, final Set<Functionality> leftFunctionalities,
			final Set<Functionality> rightFunctionalities, final boolean leftBottomToolbarVisible,
			final boolean rightBottomToolbarVisible, final DualFunctionality... dualFunctionalities)
	{
		this(new ListStore<M1>(leftProperties.key()), editorRightStore, leftProperties, rightProperties, leftColumnConfigs,
				rightColumnConfigs, leftFunctionalities, rightFunctionalities, leftBottomToolbarVisible, rightBottomToolbarVisible,
				dualFunctionalities);
	}

	/**
	 * Constructor
	 * 
	 * @param editorLeftStore
	 *           the left {@link ListStore} that will be edited
	 * @param editorRightStore
	 *           the right {@link ListStore} that will be edited
	 * @param leftProperties
	 *           {@link PropertyAccess} for left grid
	 * @param rightProperties
	 *           {@link PropertyAccess} for right grid
	 * @param leftColumnConfigs
	 *           {@link ColumnConfig} list for left grid
	 * @param rightColumnConfigs
	 *           {@link ColumnConfig} list for right grid
	 * @param leftFunctionalities
	 *           a {@link Set} of {@link Functionality} for left {@link MyEditorGrid}
	 * @param rightFunctionalities
	 *           a {@link Set} of {@link Functionality} for right {@link MyEditorGrid}
	 * @param bottomToolbarVisible
	 *           a boolean indicating whether to show bottom toobar or not
	 * @param dualFunctionalities
	 *           a succession of {@link DualFunctionality} (don't fill this argument or give
	 *           {@link DualFunctionality#ALL} to have all functionalities)
	 */
	@SuppressWarnings(
	{ "unchecked", "javadoc" })
	public MyDualEditorGrid(final ListStore<M1> editorLeftStore, final ListStore<M2> editorRightStore,
			final EditDeletePropertyAccess<M1> leftProperties, final EditDeletePropertyAccess<M2> rightProperties,
			final List<ColumnConfig<M1, ?>> leftColumnConfigs, final List<ColumnConfig<M2, ?>> rightColumnConfigs,
			final Set<Functionality> leftFunctionalities, final Set<Functionality> rightFunctionalities,
			final boolean leftBottomToolbarVisible, final boolean rightBottomToolbarVisible,
			final DualFunctionality... dualFunctionalities)
	{
		super(new MyEditorGrid<M1>(editorLeftStore, leftColumnConfigs, leftProperties, leftFunctionalities,
				leftBottomToolbarVisible, (!rightFunctionalities.isEmpty() || !leftFunctionalities.isEmpty()))
		{
			@Override
			public void invalidateUi()
			{
				// Nothing done
			}
		}, new MyEditorGrid<M2>(editorRightStore, rightColumnConfigs, rightProperties, rightFunctionalities,
				rightBottomToolbarVisible, (!rightFunctionalities.isEmpty() || !leftFunctionalities.isEmpty()))
		{
			@Override
			public void invalidateUi()
			{
				// Nothing done
			}
		}, dualFunctionalities);
		this.leftEditorGrid = (MyEditorGrid<M1>) getLeftComponent();
		this.rightEditorGrid = (MyEditorGrid<M2>) getRightComponent();
	}

	/**
	 * @return the leftEditorGrid
	 */
	public MyEditorGrid<M1> getLeftEditorGrid()
	{
		return leftEditorGrid;
	}

	/**
	 * @return the rightEditorGrid
	 */
	public MyEditorGrid<M2> getRightEditorGrid()
	{
		return rightEditorGrid;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Grid<M1> getLeftGrid(final Component leftComponent)
	{
		return ((MyEditorGrid<M1>) leftComponent).getGrid();
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Grid<M2> getRightGrid(final Component rightComponent)
	{
		return ((MyEditorGrid<M2>) rightComponent).getGrid();
	};

	/**
	 * Add a select handler on left Add button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addLeftAddSelectHandler(final AddButtonSelectHandler handler)
	{
		return getLeftEditorGrid().addHandler(handler, AddButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on left edit button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addLeftEditSelectHandler(final EditButtonSelectHandler<M1> handler)
	{
		return getLeftEditorGrid().addHandler(handler, EditButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on left delete button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addLeftDeleteSelectHandler(final DeleteButtonSelectHandler<M1> handler)
	{
		return getLeftEditorGrid().addHandler(handler, DeleteButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on left create button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addLeftCreateSelectHandler(final CreateButtonSelectHandler handler)
	{
		return getLeftEditorGrid().addHandler(handler, CreateButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on right Add button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addRightAddSelectHandler(final AddButtonSelectHandler handler)
	{
		return getRightEditorGrid().addHandler(handler, AddButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on right edit button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addRightEditSelectHandler(final EditButtonSelectHandler<M1> handler)
	{
		return getRightEditorGrid().addHandler(handler, EditButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on right delete button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addRightDeleteSelectHandler(final DeleteButtonSelectHandler<M2> handler)
	{
		return getRightEditorGrid().addHandler(handler, DeleteButtonSelectEvent.getType());
	}

	/**
	 * Add a select handler on right create button
	 * 
	 * @param handler
	 *           the handler
	 * @return the {@link HandlerRegistration}
	 */
	public HandlerRegistration addRightCreateSelectHandler(final CreateButtonSelectHandler handler)
	{
		return getRightEditorGrid().addHandler(handler, CreateButtonSelectEvent.getType());
	}
}
